package com.open.capacity.reimburse.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.open.capacity.form.dao.FormSchemeDao;
import com.open.capacity.form.dao.FormSchemeinfoDao;
import com.open.capacity.form.model.FormScheme;
import com.open.capacity.form.model.FormSchemeinfo;
import com.open.capacity.form.model.scheme.*;
import com.open.capacity.form.service.FormDbTableService;
import com.open.capacity.form.vo.FormDbTableFieldVo;
import com.open.capacity.reimburse.exception.BusinessException;
import com.open.capacity.reimburse.service.*;
import com.open.capacity.workflow.model.WFTask;
import com.open.capacity.workflow.service.WFTaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

@Slf4j
@Service
public class StandardVerifyServiceImpl implements StandardVerifyService {

    private ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private FormSchemeinfoDao schemeinfoDao;

    @Autowired
    private FormSchemeDao schemeDao;

    @Autowired
    private FormDbTableService tableService;

    @Autowired
    private StdHotelService stdHotelService;

    @Autowired
    private StdMettingService stdMettingService;

    @Autowired
    private WFTaskService taskService;


    @Override
    public void verify(String schemeinfoId, String processId, String keyValue, Map<String, Object> formDataMap) throws Exception {
        FormSchemeinfo schemeinfo = schemeinfoDao.findById(schemeinfoId);
        FormScheme scheme = schemeDao.findById(schemeinfo.getSchemeId());
        FormSchemeModel formSchemeModel = null;
        try {
            formSchemeModel = objectMapper.readValue(scheme.getScheme(), FormSchemeModel.class);
        } catch (IOException e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }

        // 主从表分类
        List<FormTableModel> cTableList = new ArrayList<>();
        for (FormTableModel table : formSchemeModel.getDbTable()) {
            if (StringUtils.isEmpty(table.getRelationName())) {
                formSchemeModel.setMainTableName(table.getName());
                formSchemeModel.setMainTablePkey(table.getField());
            } else {
                cTableList.add(table);
            }
        }

        //表单组件按表进行分类
        Map<String, List<FormCompontModel>> tableMap = new HashMap<>();
        Map<String, FormCompontModel> girdTableMap = new HashMap<>();
        for (FormTabModel tab : formSchemeModel.getData()) {
            for (FormCompontModel compont : tab.getComponts()) {
                if (StringUtils.isNotEmpty(compont.getTable())) {
                    if (!tableMap.containsKey(compont.getTable())) {
                        tableMap.put(compont.getTable(), new ArrayList<>());
                    }
                    if (compont.getType().equals("girdtable")) {
                        girdTableMap.put(compont.getTable(), compont);
                        for (GridFieldModel item : compont.getFieldsData()) {
                            FormCompontModel _compont = new FormCompontModel();
                            _compont.setField(item.getField());
                            _compont.setId(item.getField());
                            if (item.getType().equals("guid")) {
                                _compont.setType("girdguid");
                            }
                            tableMap.get(compont.getTable()).add(_compont);
                        }
                    } else {
                        tableMap.get(compont.getTable()).add(compont);
                    }
                }
            }
        }

        //数据校验
        checkData(formSchemeModel.getDbId(), formSchemeModel.getDbTable().get(0).getName(), cTableList, girdTableMap, tableMap, formDataMap);
    }

    /**
     * 数据校验
     *
     * @param dbKey       数据库关键字
     * @param tableName   表名
     * @param tableMap    表名->组件映射
     * @param formDataMap 表单数据
     */
    private void checkData(String dbKey, String tableName, List<FormTableModel> cTableList, Map<String, FormCompontModel> girdTableMap, Map<String, List<FormCompontModel>> tableMap, Map<String, Object> formDataMap) throws Exception {
        String errorMsg = "";
        //主表
        if (tableMap.containsKey(tableName) && tableMap.get(tableName).size() > 0) {
            List<FormDbTableFieldVo> list = tableService.findFieldsByTableName(dbKey, tableName);
            Map<String, String> dic = new HashMap<>();
            for (FormDbTableFieldVo item : list) {
                if (!dic.containsKey(item.getColumnName().toUpperCase())) {
                    dic.put(item.getColumnName().toUpperCase(), item.getColumnType());
                }
            }
        }

        //从表
        for (FormTableModel table : cTableList) {
            String _value = "";
            String _filed = "";
            for (FormCompontModel compont : tableMap.get(table.getRelationName())) {
                if (compont.getField().equals(table.getRelationField())) {
                    FormCompontModel newcompont = new FormCompontModel();
                    if (girdTableMap.containsKey(table.getName())) {
                        newcompont.setId(table.getField());
                    } else {
                        newcompont.setId(compont.getId());
                    }
                    newcompont.setField(table.getField());
                    _filed = table.getField();
                    _value = formDataMap.get(compont.getId()).toString();
                    tableMap.get(table.getName()).add(newcompont);
                    break;
                }
            }
            if (girdTableMap.containsKey(table.getName())) {
                try {
                    List<Map<String, Object>> girdDataJson = objectMapper.readValue(formDataMap.get(girdTableMap.get(table.getName()).getId()).toString(), List.class);
                    for (Map<String, Object> girdData : girdDataJson) {
                        girdData.put(_filed, _value);

                        List<FormDbTableFieldVo> list = tableService.findFieldsByTableName(dbKey, table.getName());
                        Map<String, String> dic = new HashMap<>();
                        for (FormDbTableFieldVo item : list) {
                            if (!dic.containsKey(item.getColumnName().toUpperCase())) {
                                dic.put(item.getColumnName().toUpperCase(), item.getColumnType());
                            }
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    log.error(e.getMessage());
                }
            }
        }

        if (StringUtils.isNotEmpty(errorMsg)) {
            throw new BusinessException(errorMsg);
        }
    }
}
